package com.googlecode.horncomb.organ.srvc.support;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.util.Assert;

import com.googlecode.horncomb.bean.filter.SimpleMapConditionSet;
import com.googlecode.horncomb.bean.order.DefaultOrder;
import com.googlecode.horncomb.organ.Group;
import com.googlecode.horncomb.organ.Person;
import com.googlecode.horncomb.organ.srvc.PersonService;
import com.googlecode.horncomb.organ.support.OrganObject;
import com.googlecode.horncomb.orm.ibatis.DefaultCommonSqlMapEntityDao;

/**
 * @author Daniel
 */
public class DefaultPersonService extends DefaultCommonSqlMapEntityDao
		implements PersonService {
	private static final long serialVersionUID = -1309349264044422241L;
	private String updateStateStatementName = "updateState";

	/**
	 * {@inheritDoc}
	 */
	public Person getById(String personId) {
		return (Person) this.getById(personId);
	}

	/**
	 * {@inheritDoc}
	 */
	public int countGroups(String personId, String[] groupNatures,
			String[] membershipNatures) {
		Assert.hasText(personId);
		Map<String, Object> membership = new HashMap<String, Object>();
		membership.put("natures", membershipNatures);
		membership.put("groupNatures", groupNatures);
		membership.put("personId", personId);
		return this.queryCount(new SimpleMapConditionSet().addConstraint(
				"membership", membership), "countGroups");
	}

	/**
	 * {@inheritDoc}
	 */
	public int countGroups(Collection<String> personIds, String[] groupNatures,
			String[] membershipNatures) {
		Assert.notEmpty(personIds);
		Map<String, Object> membership = new HashMap<String, Object>();
		membership.put("natures", membershipNatures);
		membership.put("groupNatures", groupNatures);
		membership.put("personIds", personIds);
		return this.queryCount(new SimpleMapConditionSet().addConstraint(
				"membership", membership), "countGroups");
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<Group> findGroups(String personId, String view,
			String[] groupNatures, String[] membershipNatures) {
		Map<String, Object> membership = new HashMap<String, Object>();
		membership.put("natures", membershipNatures);
		membership.put("groupNatures", groupNatures);
		membership.put("personId", personId);
		return this.query(new SimpleMapConditionSet().addConstraint(
				"membership", membership), new DefaultOrder()
				.addSortToken("MEM_GRO_ORDER_"));
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<Group> findGroups(Collection<String> personIds,
			String view, String[] groupNatures, String[] membershipNatures) {
		Map<String, Object> membership = new HashMap<String, Object>();
		membership.put("natures", membershipNatures);
		membership.put("groupNatures", groupNatures);
		membership.put("personIds", personIds);
		return this.query(new SimpleMapConditionSet().addConstraint(
				"membership", membership), new DefaultOrder()
				.addSortToken("MEM_GRO_ORDER_"));
	}

	/**
	 * {@inheritDoc}
	 */
	public Group getDefaultGroup(String personId, String groupNature,
			String membershipNature) {
		Map<String, Object> membership = new HashMap<String, Object>();
		membership.put("nature", membershipNature);
		membership.put("groupNature", groupNature);
		membership.put("personId", personId);
		return (Group) this.doGet(new SimpleMapConditionSet().addConstraint(
				"membership", membership), "getDefaultGroup");
	}

	/**
	 * {@inheritDoc}
	 */
	public void create(Person person) {
		Assert.notNull(person);
		person.setCreated(new Date());
		person.setState(OrganObject.STATE_ACTIVE);
		person.setLastUpdated(person.getCreated());
		this.insert(person);
	}

	/**
	 * @param personId
	 * @param stateDelelted
	 */
	private void updateState(String personId, String state) {
		Map<String, Object> entity = new HashMap<String, Object>();
		entity.put("state", state);
		this.doUpdate(
				new SimpleMapConditionSet().addConstraint("id", personId),
				entity, this.updateStateStatementName);
	}

	/**
	 * {@inheritDoc}
	 */
	public void removeById(String personId, boolean deleted) {
		this.updateState(personId, deleted ? OrganObject.STATE_DELELTED
				: OrganObject.STATE_ACTIVE);
	}

	/**
	 * {@inheritDoc}
	 */
	public void update(Person person) {
		Assert.notNull(person);
		person.setLastUpdated(new Date());
		this.update(person);
	}

	/**
	 * @param updateStateStatementName
	 *            the updateStateStatementName to set
	 */
	public void setUpdateStateStatementName(String updateStateStatementName) {
		this.updateStateStatementName = updateStateStatementName;
	}
}
